#ifndef		__TINY_DOUBLE_ARRAY_H_
#define		__TINY_DOUBLE_ARRAY_H_


// This library provides a static double-array dictionary which stores
// keys (strings) and their records (user-defined).


// Most functions provided by this library return the following error codes.
#define		DA_OK		0		// No error.
#define		DA_EHDL		( -1 )	// Invalid handle.
#define		DA_EMEM		( -2 )	// Memory allocation error.
#define		DA_EIO		( -3 )	// I/O error.
#define		DA_EARG		( -4 )	// Invalid argument.
#define		DA_EFMT		( -5 )	// Invalid format.
#define		DA_EMAX		( -6 )	// Too large.
#define		DA_EVER		( -7 )	// Version error.


#ifdef	__cplusplus
extern	"C"	{
#endif


// Handle of keyset.
typedef		struct DASet	*hDASet;

// Handle of dictionary.
typedef		struct DADic	*hDADic;

// Dictionary status.
typedef		struct DAStat
{
	int		nbc;		// Length of array BC.
	int		ntail;		// Length of array TAIL.
	int		size;		// Size of dictionary (bytes).
	int		nkey;		// Number of keys.
	int		maxlen;		// Maximum length of keys (except NULL character).
	int		boundary;	// Boundary of records.
}	DAStat, *hDAStat;

// Callback function for enumerating keys.
// This callback receives 3 arguments, 1st one is a key, 2nd one is a pointer
// to record, and 3rd one is the argument which has been passed to DADic_Enum().
// If this function returns other than DA_OK, the enumeration will finish.
typedef		int ( *fDACall )( const char *, void *, void * );


// Creates an empty keyset.
int		DASet_Open( hDASet *h );

// Load a keyset from a text file.
// Delimitors of keys are specified by the 3rd argument.
// For example, if "\t\r\n" has passed as the 3rd argument, tabs, carriage
// returns and line feeds are used as delimitors.
// The 4th argument specifies the size of each record.
int		DASet_Load( hDASet h, const char *path, const char *delim, int rec );

// Insert a key to a keyset.
// The 3rd argument specifies the size of each record.
int		DASet_Insert( hDASet h, const char *key, int rec );

// Destroy a keyset.
int		DASet_Close( hDASet h );


// Build a dictionary from a keyset.
// The 3rd argument specifies the boundary of records, in other words,
// all records are arranged on the specified byte boundary.
int		DADic_Build( hDADic *h, hDASet set, int boundary );

// Load a dictionary from a file.
int		DADic_Open( hDADic *h, const char *path );

// Destroy a dictionary.
int		DADic_Close( hDADic h );

// Save a dictionary to a file.
int		DADic_Save( hDADic h, const char *path );


// Get an information of a dictionary.
int		DADic_Status( hDADic h, hDAStat st );

// Call a callback function for each key in a dictionary.
// The 2nd argument will be passed to the callback function.
int		DADic_Enum( hDADic h, void *arg, fDACall call );

// Search a key which equals to an input string.
// If such a key exists, this function returns a pointer to its record.
// In case the key doesn't have a record, non-NULL pointer will be returned.
// If not, this function returns NULL.
void	*DADic_Search( hDADic h, const char *key );

// Search keys which match a prefix of an input string.
// Each call of this function returns only one key even if there are more than
// one keys to be returned, so this function should be called repeatedly until
// it returns NULL.
// In the 1st call, a pointer to a string and a pointer to an index
// zero-cleared must be passed, then this function overwrites the pointers.
void	*DADic_Prefix( hDADic h, const char **s, int *idx );

// Search keys which appears in an input string.
// Similar to DADic_Prefix, each call of this function returns only one key
// even if there are more than one keys to be returned, so this function should
// be called repeatedly until it returns NULL.
// In the 1st call, 2 pointers to a string and a pointer to an index
// zero-cleared must be passed, then this function overwrites the pointers.
void	*DADic_Infix( hDADic h, const char **start, const char **s, int *idx );


// Get an error message from an error code.
const char	*DAErr_String( int err );


#ifdef	__cplusplus
}
#endif


#endif
